package cn.zl.common.manage.dashboard;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;

public class NetworkDashboard extends BaseDashboard {

    private static final int INDEX_TIME_STAMP = 0;
    private static final int INDEX_SEND = 1;
    private static final int INDEX_ACCEPT = 2;

    // 记录网卡数据
    private final Map<String, Long[]> networkInfoMap = new ConcurrentHashMap<>();

    private final List<NetworkIF> networkIFList = new ArrayList<>();

    private final List<NetworkItem> list = new ArrayList<>(NUM);

    public NetworkDashboard(SystemInfo si) {
        super(si);
        this.init();
    }

    private void init() {
        HardwareAbstractionLayer layer = si.getHardware();
        List<NetworkIF> networkIFs = layer.getNetworkIFs();
        for (NetworkIF networkIF : networkIFs) {
            if (!networkIF.isKnownVmMacAddr()) {
                if (networkIF.getMacaddr() != null && networkIF.getIPv4addr().length > 0 && networkIF.getIPv6addr().length > 0) {
                    if (!networkInfoMap.containsKey(networkIF.getMacaddr())) {
                        networkIF.updateAttributes();
                        Long[] data = new Long[]{networkIF.getTimeStamp(), networkIF.getBytesSent(), networkIF.getBytesRecv()};
                        networkInfoMap.put(networkIF.getMacaddr(), data);
                    }
                    networkIFList.add(networkIF);
                }
            }
        }
    }

    public void getNetworkInfo(String now) {
        if (list.size() >= NUM) {
            list.removeFirst();
        }
        NetworkItem item = new NetworkItem();
        item.time = now;
        item.send = 0;
        item.accept = 0;
        for (NetworkIF networkIF : networkIFList) {
            if (networkIF.updateAttributes()) {
                if (networkIF.getIPv4addr().length > 0 && networkIF.getIPv6addr().length > 0) {
                    //计算
                    Long[] oldData = networkInfoMap.get(networkIF.getMacaddr());
                    long time = oldData[INDEX_TIME_STAMP] - networkIF.getTimeStamp();
                    if (time == 0) {
                        continue;
                    }
                    long send = Math.round(((double) ((oldData[INDEX_SEND] - networkIF.getBytesSent()) * 8) / time * 1000) / 1024.0);
                    long accept = Math.round(((double) ((oldData[INDEX_ACCEPT] - networkIF.getBytesRecv()) * 8) / time * 1000) / 1024.0);
                    item.send = item.send + send;
                    item.accept = item.accept + accept;

                    Long[] newData = new Long[]{networkIF.getTimeStamp(), networkIF.getBytesSent(), networkIF.getBytesRecv()};
                    networkInfoMap.put(networkIF.getMacaddr(), newData);
                }
            }
        }
        list.add(item);
    }

    @Override
    public JSONObject encode() {
        if(list.isEmpty()){
            return new JSONObject();
        } else {
            return list.getLast().encode();
        }
    }

    public static class NetworkItem implements BaseDashboard.IRate, Comparable<NetworkItem> {
        String time;
        long send;
        long accept;

        public JSONObject encode() {
            JSONObject json = new JSONObject();
            json.put("time", time);
            json.put("send", send);
            json.put("accept", accept);
            return json;
        }

        @Override
        public int compareTo(NetworkItem o) {
            return this.time.compareTo(o.time);
        }
    }

}
